#include <iostream>
#include "httplib.h"
#include "add_contact.pb.h"
using namespace httplib;

class ContactException
{
public:
	ContactException(std::string str = "a problem") : message(str)
	{
	}
	std::string what() const
	{
		return message;
	}

private:
	std::string message;
};

void PrintAddContact(add_contact::AddContactRequest &req)
{
	std::cout << "姓名：" << req.name() << std::endl;
	std::cout << "年龄：" << req.age() << std::endl;
	int j = 1;
	for (const auto phone : req.phone())
	{
		std::cout << "电话(" << j++ << "): " << phone.number() << "(" << phone.PhoneType_Name(phone.type())
				  << ")" << std::endl;
	}
}

static unsigned int random_char()
{
	// 用于随机数引擎获得随机种子
	std::random_device rd;
	// mt19937是c++11新特性，它是一种随机数算法，用法与rand()函数类似，但是mt19937
	// 具有速度快，周期长的特点
	// 作用是生成伪随机数
	std::mt19937 gen(rd());
	// 随机生成一个整数i 范围[0, 255]
	std::uniform_int_distribution<> dis(0, 255);
	return dis(gen);
}
// 生成 UUID （通用唯一标识符）
static std::string generate_hex(const unsigned int len)
{
	std::stringstream ss;
	// 生成 len 个16进制随机数，将其拼接而成
	for (auto i = 0; i < len; i++)
	{
		const auto rc = random_char();
		std::stringstream hexstream;
		hexstream << std::hex << rc;
		auto hex = hexstream.str();
		ss << (hex.length() < 2 ? '0' + hex : hex);
	}
	return ss.str();
}

int main()
{
	std::cout << "-------服务启动---------" << std::endl;
	Server server;
	server.Post("/contacts/add", [](const Request &req, Response &resp)
				{
					std::cout << "接受到Post请求" << std::endl;
					
					add_contact::AddContactRequest request;   // 接受反序列化后的内容
					add_contact::AddContactResponse response; // 序列化发出响应

					try
					{
						// 对收到的信息进行反序列化
						if (!request.ParseFromString(req.body))
						{
							throw ContactException("反序列化失败");
						}

						// 新增联系人，打印练习人
						PrintAddContact(request);

						// 构造response resp.body
						response.set_success(true);
						response.set_uid(generate_hex(10));

						// 序列化response
						std::string resp_str;
						if(!response.SerializeToString(&resp_str))
						{
							throw ContactException("序列化失败");
						}
						resp.body = resp_str;
						resp.status = 200;
						resp.set_header("Content-Type","application/protobuf");

					}
					catch (const ContactException &e)
					{
						resp.status = 500;
						response.set_success(false);
						response.set_error(e.what());
						// 序列化
						std::string resp_str; 
						if(response.SerializeToString(&resp_str))
						{
							resp.body = resp_str;
							resp.set_header("Content-Type","application/protobuf");

						}
						std::cout << "/contacts/add 发生异常，异常信息：" << e.what() << std::endl;
					} });

	server.listen("0.0.0.0", 8080);
	return 0;
}

// int main()
// {
// 	std::cout << "-------服务启动---------" << std::endl;
// 	Server server;
// 	server.Post("/test-post",[](const Request& req,Response& resp){
// 		std::cout << "接受到Post请求" << std::endl;
// 		resp.status = 200;
// 	});

// 	server.Get("/test-get",[](const Request& req,Response& resp){
// 		std::cout << "接受到Get请求" << std::endl;
// 		resp.status = 200;
// 	});
// 	server.listen("0.0.0.0",8080);
// 	return 0;
// }